package net.luerything.restlet.gwt.rpc;

import org.restlet.data.CharacterSet;
import org.restlet.representation.Representation;
import org.restlet.representation.Variant;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;

/**
 * @author keke
 */
public abstract class GwtRpcResource extends ServerResource {
  public static final String GWT_RPC_KEY = "__gwt_rpc__";
  private GwtRpc gwtRpc;


  public GwtRpcResource() {

  }

  public GwtRpcResource(final GwtRpc gwtRpc) {
    this.gwtRpc = gwtRpc;
  }

  public void setGwtRpc(final GwtRpc gwtRpc) {
    this.gwtRpc = gwtRpc;
  }

  @Override
  protected void doInit() throws ResourceException {
    super.doInit();
    final Variant variant = new Variant(Commons.GWT_RPC);
    variant.setCharacterSet(CharacterSet.UTF_8);
    getVariants().add(variant);
  }

  @Override
  protected Representation post(final Representation entity, final Variant variant) throws ResourceException {
    final GwtRpc gwtRpc = getGwtRpc();
    assert gwtRpc != null;
    final Commons.Result result = gwtRpc.doRpc(entity);
    getResponse().setStatus(result.getStatus());
    return result.getResult();
  }

  protected GwtRpc getGwtRpc() {
    if (gwtRpc == null) {
      if (getApplication() instanceof HasGwtRpc) {
        gwtRpc = ((HasGwtRpc) getApplication()).getGwtRpc();
        assert gwtRpc != null;
      }
      if (gwtRpc == null) {
        gwtRpc = checkAttrValue(getRequestAttributes().get(GWT_RPC_KEY));
      }
      if (gwtRpc == null) {
        gwtRpc = checkAttrValue(getContext().getAttributes().get(GWT_RPC_KEY));
      }
    }
    return gwtRpc;
  }

  private GwtRpc checkAttrValue(Object value) {
    if (value != null && value instanceof GwtRpc) {
      return (GwtRpc) value;
    }
    return null;
  }
}
